#include "../../common/etcd.hpp"
#include <gflags/gflags.h>
#include <thread>
#include "main.pb.h"
#include <brpc/server.h>
#include <butil/logging.h>


DEFINE_bool(run_mode, false, "程序运行模式， false调试; true发布;");
DEFINE_string(log_file, "", "发布模式下，用于指定日志的输出文件");
DEFINE_int32(log_level, 0, "发布模式下，用于指定日志的输出等级");

DEFINE_string(etcd_host, "http://127.0.0.1:2379", "服务注册中心地址");
DEFINE_string(base_service, "/service", "服务监控根目录");
DEFINE_string(instance_name, "/echo/instance", "当前实例名称");
DEFINE_string(access_host, "127.0.0.1:8080", "当前实例的外部访问地址");
DEFINE_int32(listen_port, 8080, "rpc服务器监听端口");

// 自定义服务类：继承 Protobuf 生成的 EchoService 基类
class EchoServiceImpl : public example::EchoService {
public:
    void Echo(google::protobuf::RpcController* controller,
              const ::example::EchoRequest* request, //客户端请求
              ::example::EchoResponse* response,     //服务端请求
              ::google::protobuf::Closure* done) {   //回调（用于通知RPC完成）
                
            //自动管理done的生命周期（避免内存泄漏）
            brpc::ClosureGuard rpc_guard(done);  

            //处理请求：打印收到的消息
            std::cout << "收到消息：" << request->message() << std::endl;

            //构造响应：在请求消息后添加后缀
            std::string str = request->message() + "--这是响应！！";
            response->set_message(str);
        }
};

int main(int argc, char *argv[]){
    google::ParseCommandLineFlags(&argc, &argv, true);

    init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);

    //服务改造思想: 
    //1. 关闭BRPC默认的日志（可选）
    logging::LoggingSettings settings;
    settings.logging_dest = logging::LoggingDestination::LOG_TO_NONE;
    logging::InitLogging(settings);

    //2. 初始化BRPC服务器
    brpc::Server server;

    //3. 注册服务：将EchoServiceImpl实例添加到服务器
    EchoServiceImpl echo_service;
    int ret = server.AddService(&echo_service,
    brpc::ServiceOwnership::SERVER_DOESNT_OWN_SERVICE);

    if (ret == -1) {
        std::cout << "添加Rpc服务失败!\n";
        return -1;
    }

    //4. 配置并启动服务器
    brpc::ServerOptions option;
    option.idle_timeout_sec = -1; //链接无超时（-1表示禁用）
    option.num_threads = 1;       //IO线程数量为1
    ret = server.Start(FLAGS_listen_port, &option); //监听8080端口
    if (ret == -1) {
        std::cout << "启动服务器失败！\n";
        return -1;
    }

    //5. 注册服务
    Registry::ptr rclient = std::make_shared<Registry>(FLAGS_etcd_host);
    //服务注册的核心目标是 “让注册中心知道‘某个具体节点’提供了‘某类服务’”，需要携带 “节点唯一性信息”，
    //因此必须用 服务实例标识（/service/echo/instance）：
    rclient->registry(FLAGS_base_service + FLAGS_instance_name, FLAGS_access_host);

    //阻塞等待服务器退出（直到收到终止信号）
    server.RunUntilAskedToQuit();

    std::this_thread::sleep_for(std::chrono::seconds(600));
    return 0;
}
